<?php

namespace app\task\command;

use app\common\model\Mobile;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Db;

/**
 * 话费充值订单轮询
 */
class MobileReOrder extends Command
{
    /**
     * 配置指令[每分钟执行1次].
     * 
     * sudo -u www php /www/wwwroot/api/think mobile:reOrder
     */
    protected function configure()
    {
        $this->setName('mobile:reOrder')
            ->setDescription('mobile recreate order');
    }

    /**
     * 执行指令.
     *
     * @throws \think\admin\Exception
     */
    protected function execute(Input $input, Output $output)
    {
        echo '话费失败订单开始重新下单--' . PHP_EOL;
        $lockKey = 'mobile_re_order_lock_key';
        $lockVal = cache($lockKey);
        if ($lockVal) {
            echo '还在处理呢' . PHP_EOL;

            return true;
        }

        cache($lockKey, 1, 600);

        $list = Db::name('mobile_order')
            ->where('supplier_status', 99)
            ->limit(300)
            ->select()
            ->toArray();
        if (empty($list)) {
            cache($lockKey, null);
            echo '处理完了' . PHP_EOL;
            return true;
        }

        // 代理商轮询通道配置
        $agentIds = array_unique(array_column($list, 'agent_id'));
        $agent = Db::name('agent')
            ->whereIn('id', $agentIds)
            ->column('mobile_supplier_ids', 'id');
        $supplierIds = [];
        foreach ($agent as $k => $v) {
            $v = json_decode($v, true) ?? [];
            $agent[$k] = $v;
            $supplierIds = array_merge($supplierIds, $v);
        }
        // 新供应商通道及折扣
        $supplierIds = array_filter(array_unique($supplierIds));
        $supplier = Db::name('mobile_supplier')
            ->whereIn('id', $supplierIds)
            ->where('is_deleted', 0)
            ->column('yidong_fast, yidong_slow, liantong_fast, liantong_slow,
            dianxin_fast, dianxin_slow, discount_fast_all, discount_slow_all', 'id');
        foreach ($supplier as $k => $v) {
            foreach ($v as $field => $value) {
                if ($field == 'id') {
                    continue;
                }
                $supplier[$k][$field] = json_decode($value, true);
            }
            $supplier[$k]['other_slow'] = $supplier[$k]['yidong_slow'];
            $supplier[$k]['other_fast'] = $supplier[$k]['yidong_fast'];
        }
        $map = [
            1 => 'yidong',
            2 => 'liantong',
            3 => 'dianxin',
            -1 => 'other',
        ];
        
        // 代理商-供应商关联
        $tmp = Db::name('agent_mobile_supplier')
            ->field('agent_id, mobile_supplier_id')
            ->whereIn('agent_id', $agentIds)
            ->select();
        $agentSupplier = [];
        foreach ($tmp as $v) {
            $agentSupplier[$v['agent_id']][] = $v['mobile_supplier_id'];
        }
        unset($tmp);

        $done = 0;
        foreach ($list as $order) {
            // 不重试，直接失败
            // $this->orderFinish($order);
            // $done += 1;
            // continue;

            // 第几轮次的轮询，订单号规则：sub_order_id + 轮次，例：2108271424446508001_21
            $arr = explode('_', $order['sub_order_id']);
            $round = ($arr[1] ?? 0) + 1;
            if (empty($agent[$order['agent_id']][$round])) {
                $this->orderFinish($order);
                continue;
            }
            $maxRound = count($agent[$order['agent_id']]);
            $amount = fen2yuan($order['amount']);
            $ispType = getMobileIsp($order['mobile']);
            $fieldName = $map[$ispType];
            if ($order['order_type'] == 1) {
                $fieldName .= '_slow';
            } else {
                $fieldName .= '_fast';
            }
            // 当前供应商不可用，切换下个通道，都不可用，直接失败
            $newSupplierId = 0;
            $supplierDiscount = 0;
            for (; $round < $maxRound; $round++) {
                $newSupplierId = $agent[$order['agent_id']][$round] ?? 0; // 新的供应商
                if (empty($agentSupplier[$order['agent_id']]) || !in_array($newSupplierId, $agentSupplier[$order['agent_id']])) {
                    $newSupplierId = 0;
                    continue;
                }
                // 供应商对应面额的通道是否有开启
                if (empty($supplier[$newSupplierId]) || !in_array($amount, $supplier[$newSupplierId][$fieldName])) {
                    $newSupplierId = 0;
                    continue;
                }
                if ($order['order_type'] == 1) {
                    $discountField = 'discount_slow_all';
                } else {
                    $discountField = 'discount_fast_all';
                }
                $max = max($supplier[$newSupplierId][$discountField]);
                $supplierDiscount = $supplier[$newSupplierId][$discountField][$ispType] ?? $max;
                if ($newSupplierId && $supplierDiscount) {
                    break;
                }
            }
            $newSubOrderId = $arr[0] . '_' . $round; // 新的订单号

            if (empty($order['change_flag']) || empty($newSupplierId) || empty($supplierDiscount)) {
                $remark = $order['remark'] . PHP_EOL . '下单失败【0】';
                $this->orderFinish($order, $remark);
                continue;
            }

            // 新的供应商折扣
            $supplierPrice = intval(strval($amount * $supplierDiscount));
            $platformProfit = $order['settle_price'] - $supplierPrice;

            // 选择新的供应商，重新下单
            Db::startTrans();
            try {
                $id = $order['id'];
                $order['origin_id'] = $id;
                unset($order['id']);
                Db::name('mobile_order_history')
                    ->strict(false)
                    ->insert($order);
                $res = Db::name('mobile_order')
                    ->where('id', $id)
                    ->where('supplier_status', 99)
                    ->where('mobile_supplier_id', $order['mobile_supplier_id'])
                    ->where('sub_order_id', $order['sub_order_id'])
                    ->update([
                        'supplier_status' => 1,
                        'mobile_supplier_id' => $newSupplierId,
                        'sub_order_id' => $newSubOrderId,
                        'supplier_discount' => $supplierDiscount,
                        'supplier_price' => $supplierPrice,
                        'supplier_order_no' => '',
                        'platform_profit' => $platformProfit,
                        'finish_time' => 0,
                        'remark' => '',
                    ]);
                if (!$res) {
                    Db::rollback();
                } else {
                    ++$done;

                    Db::commit();
                }
            } catch (\Exception $e) {
                Db::rollback();
                echo '重新下单失败：' . $e->getMessage() . PHP_EOL;
            }
        }

        cache($lockKey, null);

        echo '话费失败订单结束重新下单：成功下 ' . $done . ' 单' . PHP_EOL;
    }

    private function orderFinish($order, $remark = '')
    {
        $order['is_finish'] = 1;
        $update = [
            'refund_status' => 2,
            'supplier_status' => 4,
            'finish_time' => time(),
        ];
        if ($remark) {
            $update['remark'] = $remark;
        }
        Mobile::handleNotify($order, $update);
    }
}
